lexer grammar JSXLexer;

// 标签解析开始
TAG_OPEN: '<' [ \t]* NAME -> pushMode(HTML), pushMode(TAG);
// 匹配其余js表达式
JS_LP:'{' -> pushMode(JSX);
JS: .*?;

mode JSX;
JSX_TAG_OPEN: '<' [ \t]* NAME -> pushMode(HTML), pushMode(TAG);
// 等到}嵌套完成 需要判断匹配的嵌套
JSX_RP: '}' ->popMode;
JXS: .*?;

// 开始标签的解析
mode TAG;
// 开始标签的闭合<div>
TAG_CLOSE: '>' -> popMode;
// 单标签闭合</span>
TAG_SLASH_CLOSE: '/' [ \t]* '>' -> popMode, popMode;
// 属性的名称[a-zA-Z]
TAG_NAME: NAME;
// 属性的=
TAG_EQUALS: '=';
// ' | " 开始的属性值
TAG_VALUE: DOUBLE_QUOTE_STRING | SINGLE_QUOTE_STRING;
// { jsx表达式属性值
TAG_LP: '{' -> pushMode(JSX);
// 空格跳过
TAG_WHITESPACE: [ \t\r\n] -> skip;

// html的除了开始标签外的内容
mode HTML;
// html嵌套标签<div><span>
HTML_TAG_OPEN: '<' [ \t]* NAME -> pushMode(HTML), pushMode(TAG);
// html闭合标签<div></div>
HTML_CLOSE: '<' [ \t]* '/' [ \t]* NAME [ \t]* '>' -> popMode;
// html的内容为jsx表达式
HTML_LP: '{' -> pushMode(JSX);
// html的内容空白保留
HTML_WS: (' ' | '\t' | '\r'? '\n')+;
// html的文本内容
HTML_TEXT: .*?;


fragment LP : '{';
fragment RP : '}';

fragment DOUBLE_QUOTE_STRING: '"' ~["]* '"';

fragment SINGLE_QUOTE_STRING: '\'' ~[']* '\'';

fragment NAME : NameStartChar NameChar*;

fragment NameChar:
  NameStartChar
  | '-'
  | '_'
  | '.'
  | DIGIT
  ;

fragment NameStartChar:[a-zA-Z];

fragment DIGIT: [0-9];


